package com.jltx.storage.demo

import android.Manifest
import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.jltx.storage.downloader.FileCallback
import com.jltx.storage.downloader.MultiRequestResult
import com.jltx.storage.downloader.RequestResult
import com.jltx.storage.downloader.StorageDownloader
import com.tbruyelle.rxpermissions2.Permission
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File

class MainActivity : AppCompatActivity(), View.OnClickListener {

    companion object {
        const val TAG = "RxDownload"
    }

    private val rxPermissions: RxPermissions = RxPermissions(this)
    private val singleObj = Any()
    private val multiObj = Any()
    private var isSingleLoading = false
    private var isMultiLoading = false
    private var multiDisposable: Disposable? = null
    private var isSingleCorcoutines = false
    private val singleCorcoutinesObj = Any()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        StorageDownloader.init(this)
        com.jltx.storage.coroutinesdownloader.StorageDownloader.init(this)
        progress_pb.max = 100
        download_btn.setOnClickListener(this)

        multi_progress_pb.max = 100
        multi_download_btn.setOnClickListener(this)

        corcoutines_download_btn.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.download_btn -> {
                if (isSingleLoading) {
                    isSingleLoading = false
                    download_btn.setText(getString(R.string.reload))
                    StorageDownloader.cancel(singleObj)
                } else {
                    downSingleForPermission()
                }
            }
            R.id.multi_download_btn -> {
                if (isMultiLoading) {
                    isMultiLoading = false
                    StorageDownloader.cancel(multiObj)
                    multi_download_btn.setText(getString(R.string.reload))
                } else {
                    downMultiForPermission()
                }
            }

            R.id.corcoutines_download_btn -> {
                downCorcoutinesSingleForPermission()
            }
            else -> {
            }
        }
    }

    private fun downSingleForPermission() {
        rxPermissions.requestEachCombined(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
        )
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe(Consumer<Permission> { permission ->
                if (permission.granted) {
                    // All permissions are granted !
                    downSingle()
                } else if (permission.shouldShowRequestPermissionRationale) {
                    // At least one denied permission without ask never again
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限才可以正常使用哦")
                        .setPositiveButton(
                            "确定",
                            { dialog, which -> downSingleForPermission() })
                        .setNegativeButton(
                            "取消",
                            DialogInterface.OnClickListener { dialog, which ->
                                AlertDialog.Builder(this@MainActivity)
                                    .setTitle("权限申请")
                                    .setMessage("打开相册需要访问读写存储权限才可以正常使用哦！")
                                    .setPositiveButton("确定", null)
                                    .create()
                                    .show()
                            })
                        .create()
                        .show()
                } else { // At least one denied permission with ask never again
                    // Need to go to the settings
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限，不开启将无法正常使用！")
                        .setPositiveButton(
                            "确定",
                            DialogInterface.OnClickListener { dialog, which ->
                                //调用系统设置页面
                                startInstalledAppDetailsActivity(this@MainActivity)
                            })
                        .setNegativeButton("取消", null)
                        .create()
                        .show()
                }
            })
    }

    private fun downSingle() {
        val url = "http://v2.dwstatic.com/zbshenqi/SOURCEHANSERIFCNBOLD.otf"
        val localPath =
            getExternalFilesDir(null).toString() + File.separator + "SOURCEHANSERIFCNBOLD.otf"
        StorageDownloader
            .download(singleObj, url, localPath, object : FileCallback<RequestResult<*>>() {
                override fun onSubscribe(d: Disposable?) {
                    super.onSubscribe(d)
                    isSingleLoading = true
                    download_btn.text = getString(R.string.cancel)
                }

                override fun onSuccess(tag: Any?, result: RequestResult<*>?) {
                    isSingleLoading = false
                    download_btn.setText(getString(R.string.reload))
                    onUpdateProgress(100)
                }

                override fun onFailure(tag: Any?, result: RequestResult<*>?) {
                    isSingleLoading = false
                    download_btn.setText(getString(R.string.reload))
                }

                override fun onLoading(tag: Any?, result: RequestResult<*>?) {
                    super.onLoading(tag, result)
                    result?.let {
                        val percent: Float = it.progress * 1.0f / it.total
                        onUpdateProgress((100 * percent).toInt())
                    }
                }

                private fun onUpdateProgress(progress: Int) {
                    progress_tv.text = String.format("%d%s", progress, "%")
                    progress_pb.progress = progress
                }
            })
    }

    private fun downMultiForPermission() {
        rxPermissions.requestEachCombined(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
        )
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe { permission ->
                if (permission.granted) { // All permissions are granted !
                    downMulti()
                } else if (permission.shouldShowRequestPermissionRationale) {
                    // At least one denied permission without ask never again
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限才可以正常使用哦")
                        .setPositiveButton(
                            "确定"
                        ) { dialog, which -> downMultiForPermission() }
                        .setNegativeButton(
                            "取消"
                        ) { dialog, which ->
                            AlertDialog.Builder(this@MainActivity)
                                .setTitle("权限申请")
                                .setMessage("打开相册需要访问读写存储权限才可以正常使用哦！")
                                .setPositiveButton("确定", null)
                                .create()
                                .show()
                        }
                        .create()
                        .show()
                } else { // At least one denied permission with ask never again
                    // Need to go to the settings
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限，不开启将无法正常使用！")
                        .setPositiveButton(
                            "确定",
                            DialogInterface.OnClickListener { dialog, which ->
                                //调用系统设置页面
                                startInstalledAppDetailsActivity(this@MainActivity)
                            })
                        .setNegativeButton("取消", null)
                        .create()
                        .show()
                }
            }
    }


    private fun downMulti() {
        val urlList: MutableList<String> =
            ArrayList()
        urlList.add("http://v2.dwstatic.com/zbshenqi/MSYHBD.ttf")
        urlList.add("http://v2.dwstatic.com/zbshenqi/Msyh.ttf")
        urlList.add("http://v2.dwstatic.com/zbshenqi/AdobeHeitiStd-Regular.otf")
        urlList.add("http://v2.dwstatic.com/zbshenqi/STKaiti.ttf")
        urlList.add("http://v2.dwstatic.com/zbshenqi/PingFangSC-Medium.otf")
        urlList.add("http://v2.dwstatic.com/zbshenqi/PingFang-SC-Bold.ttf")
        val dir = getExternalFilesDir(null).toString() + File.separator
        val pathList: MutableList<String> =
            ArrayList()
        pathList.add(dir + "MSYHBD.ttf")
        pathList.add(dir + "Msyh.ttf")
        pathList.add(dir + "AdobeHeitiStd-Regular.otf")
        pathList.add(dir + "STKaiti.ttf")
        pathList.add(dir + "PingFangSC-Medium.otf")
        pathList.add(dir + "PingFang-SC-Bold.ttf")

        StorageDownloader
            .downloadMulti(
                multiObj,
                urlList,
                pathList,
                object : FileCallback<MultiRequestResult>() {
                    override fun onSuccess(tag: Any?, result: MultiRequestResult) {
                        isMultiLoading = false
                        result.let {
                            Log.d(TAG, "onSuccess.count:${it.count}")
                            result.successList.forEach { requestResult ->
                                Log.d(TAG, "RequestResult$requestResult")
                            }
                        }
                    }

                    override fun onFailure(tag: Any?, result: MultiRequestResult) {
                        isMultiLoading = false
                        Log.d(
                            TAG,
                            "onFailure.count:${result.count},successSize:${result.successList.size}"
                        )
                        result.successList?.forEach { requestResult ->
                            Log.d(TAG, "RequestResult$requestResult")
                        }
                    }

                    override fun onLoading(tag: Any?, result: MultiRequestResult) {
                        super.onLoading(tag, result)
                        isMultiLoading = true
                        onUpdateProgress((100 * result.curProgress).toInt())
                    }

                    private fun onUpdateProgress(progress: Int) {
                        multi_progress_tv.setText(String.format("%d%s", progress, "%"))
                        multi_progress_pb.setProgress(progress)
                    }
                },
                object : FileCallback<RequestResult<*>>() {
                    override fun onSuccess(tag: Any?, result: RequestResult<*>?) {
                        Log.d(TAG, "onSuccess.result=>$result")
                    }

                    override fun onFailure(tag: Any?, result: RequestResult<*>?) {
                        Log.e(TAG, "onFailure.error=>" + result?.error.toString())
                    }

                    override fun onLoading(tag: Any?, result: RequestResult<*>?) {
                        super.onLoading(tag, result)
                        Log.d(TAG, "onLoading.result=>$result")
                    }
                })
    }

    private fun startInstalledAppDetailsActivity(context: Activity?) {
        if (context == null) {
            return
        }
        val i = Intent()
        i.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        i.addCategory(Intent.CATEGORY_DEFAULT)
        i.data = Uri.parse("package:" + context.packageName)
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
        context.startActivity(i)
    }

    private fun downCorcoutinesSingleForPermission() {
        rxPermissions.requestEachCombined(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
        )
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe(Consumer<Permission> { permission ->
                if (permission.granted) { // All permissions are granted !
                    downCorcoutinesSingle()
                } else if (permission.shouldShowRequestPermissionRationale) {
                    // At least one denied permission without ask never again
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限才可以正常使用哦")
                        .setPositiveButton(
                            "确定"
                        ) { dialog, which -> downCorcoutinesSingleForPermission() }
                        .setNegativeButton(
                            "取消"
                        ) { dialog, which ->
                            AlertDialog.Builder(this@MainActivity)
                                .setTitle("权限申请")
                                .setMessage("打开相册需要访问读写存储权限才可以正常使用哦！")
                                .setPositiveButton("确定", null)
                                .create()
                                .show()
                        }
                        .create()
                        .show()
                } else { // At least one denied permission with ask never again
                    // Need to go to the settings
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("权限申请")
                        .setMessage("打开相册需要访问读写存储权限，不开启将无法正常使用！")
                        .setPositiveButton(
                            "确定",
                            DialogInterface.OnClickListener { dialog, which ->
                                //调用系统设置页面
                                startInstalledAppDetailsActivity(this@MainActivity)
                            })
                        .setNegativeButton("取消", null)
                        .create()
                        .show()
                }
            })
    }

    private fun downCorcoutinesSingle() {
        val url = "http://v2.dwstatic.com/zbshenqi/SOURCEHANSERIFCNBOLD.otf"
        val localPath =
            getExternalFilesDir(null).toString() + File.separator + "SOURCEHANSERIFCNBOLD.otf"
        com.jltx.storage.coroutinesdownloader.StorageDownloader.download(
            url,
            url,
            localPath,
            object :
                com.jltx.storage.coroutinesdownloader.FileCallback<com.jltx.storage.coroutinesdownloader.RequestResult>() {
                override fun onStart(tag: Any?) {
                    super.onStart(tag)
                    isSingleCorcoutines = true
                }

                override fun onLoading(
                    tag: Any?,
                    result: com.jltx.storage.coroutinesdownloader.RequestResult
                ) {
                    super.onLoading(tag, result)
                    val percent: Float = result.progress * 1.0f / result.total
                    onUpdateProgress((100 * percent).toInt())
                }

                override fun onSuccess(
                    tag: Any?,
                    result: com.jltx.storage.coroutinesdownloader.RequestResult
                ) {
                    isSingleCorcoutines = false
                    corcoutines_download_btn.setText(getString(R.string.reload))
                }

                override fun onFailure(
                    tag: Any?,
                    result: com.jltx.storage.coroutinesdownloader.RequestResult
                ) {
                    isSingleCorcoutines = false
                    corcoutines_download_btn.text = getString(R.string.reload)
                }

                private fun onUpdateProgress(progress: Int) {
                    corcoutines_progress_tv.text = String.format("%d%s", progress, "%")
                    corcoutines_progress_pb.progress = progress
                }
            })
    }
}
